﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Godot.core.os
{
    public abstract class OS : Object
    {
        public enum ScreenOrientation
        {
            SCREEN_LANDSCAPE,
            SCREEN_PORTRAIT,
            SCREEN_REVERSE_LANDSCAPE,
            SCREEN_REVERSE_PORTRAIT,
            SCREEN_SENSOR_LANDSCAPE,
            SCREEN_SENSOR_PORTRAIT,
            SCREEN_SENSOR,
        };

        public enum RenderThreadMode
        {

            RENDER_THREAD_UNSAFE,
            RENDER_THREAD_SAFE,
            RENDER_SEPARATE_THREAD
        };

        public class VideoMode 
        {	
		    public int width,height;
		    public bool fullscreen;
		    public bool resizable;
		    
            public float get_aspect()
            { 
                return (float)width/(float)height; 
            }

		    public VideoMode(int p_width = 640,int p_height = 480,bool p_fullscreen = false, bool p_resizable = true) 
            { 
                width = p_width; 
                height = p_height; 
                fullscreen = p_fullscreen; 
                resizable = p_resizable; 
            }
	    }      

        public static OS singleton
        {
            get { return _singleton; }
        }

        public OS()
        {
            //_last_error=NULL;
	        _frames_drawn = 0;
	        _singleton = this;
	        _ips = 60;
	        _low_processor_usage_mode = false;
	        _verbose_stdout = false;
	        _frame_delay = 0;
	        _no_window = false;
	        _exit_code = 0;
            _orientation = ScreenOrientation.SCREEN_LANDSCAPE;
	        _fps = 1;
	        _target_fps = 0;
            _render_thread_mode = RenderThreadMode.RENDER_THREAD_SAFE;
	        //Math::seed(1234567);
        }

        public string get_executable_path()
        {
	        return _execpath;
        }

        public List<string> get_cmdline_args()
        {
            return new List<string>();
        }

        internal string get_data_dir()
        {
            throw new NotImplementedException();
        }

        internal void set_cmdline(string p_execpath, List<string> p_args)
        {
            _execpath = p_execpath;
            _cmdline = p_args;
        }

        public virtual void set_target_fps(int p_fps)
        {
            _target_fps = p_fps > 0 ? p_fps : _target_fps;
        }

        public virtual string get_resource_dir()
        {
            return Globals.singleton.get_resource_path();
        }

        public virtual int get_iterations_per_second()
        {
            return _ips;
        }

        public virtual void set_iterations_per_second(int p_ips) 
        {
            _ips = p_ips;
        }

        public virtual void set_screen_orientation(ScreenOrientation screenOrientation)
        {
            
        }

        public abstract ulong get_ticks_usec();

        public abstract string get_audio_driver_name(int p_driver);

        public abstract string get_video_driver_name(int p_driver);

        public abstract void initialize(VideoMode p_desired,int p_video_driver, int p_audio_driver);
        
        public abstract void initialize_core();

        public abstract VideoMode get_default_video_mode();

        public abstract void set_main_loop(MainLoop main_loop);

        public abstract void alert(string p_alert, string p_title = "ALERT!");

        public abstract string get_name();

        public abstract MainLoop get_main_loop();

        public virtual string get_locale()
        {
            return "en";
        }


        public abstract void set_window_title(string appname);

        public abstract VideoMode get_video_mode(int p_screen = 0);

        public abstract int get_video_driver_count();

        public abstract int get_audio_driver_count();

        private static OS _singleton;
        private string _execpath;
        private string _custom_level;
        private List<string> _cmdline;
        protected int _ips;
        private bool _low_processor_usage_mode;
        private bool _verbose_stdout;
        private string _local_clipboard;
        private ulong _frames_drawn;
        private uint _frame_delay;
        private bool _no_window;
        private int _exit_code;
        private ScreenOrientation _orientation;
        internal RenderThreadMode _render_thread_mode;

        private float _fps;
        private int _target_fps;

        private string last_error;

        
    }
}
